#pragma once
#include <Rz/Object.h>
#include "EventArgs.h"
#include <vector>	// List?


#ifdef RZ_COMPILER_MSVC
#	pragma pack(push, 1) 	// get aware of warning 'alignment of a member was sensitive to packing'
#endif

#include "IEventCallback.h"

#define RZ_EVENTHANDLER(fn)	::Rz::Event::MakeCallback(this, fn)

namespace Rz {

class Event
	: public Object
{
    public:
		RZ_RTTI(Rz, Event);
		RZ_RTTI_IMPLEMENTS(Object);
		RZ_RTTI_END;

        Event();
        ~Event();

		Event& operator += (IEventCallback::FunctionType fn);
        Event& operator += (IEventCallback* fn);

        Event& operator -= (IEventCallback* fn);

        void operator () (Object& sender, EventArgs& e);

        template <typename T, typename ArgsT>
        static IEventCallback* MakeCallback(T* object, void (T::*callback)(Object&, ArgsT))
        {
            RZ_EVENT_CHECK_ARGUMENT_ERROR;
            return new EventCallbackMethodPointer(object, callback);
        }

    private:
        std::vector<Ptr<IEventCallback>> _events;
};

}

#ifdef RZ_COMPILER_MSVC
#	pragma pack(pop, 1)
#endif
